<template>
  <el-card class="el-card--has-heading success">
    <div slot="header">
      <span>角色管理</span>
      <el-button
        style="float: right; padding: 3px 0"
        type="text"
        @click="onClickCreate"
        v-auth:[$P.system.role.create]
      >创建角色</el-button>
    </div>
    <v-table
      :dataSource="dataSource"
      :columns="filterColumn(columns,[$P.system.role.update, $P.system.role.delete])"
      :total="total"
      :loading="loading"
      v-bind="bindProps"
      v-on="bindListeners"
    ></v-table>

    <Modal
      :title="roleModalType === 'create' ? $t('createText') : $t('updateText')"
      :loading="roleModalLoading"
      :visible.sync="roleModalVisible"
      :width="$V.size.sm"
      :onOk="() => handleRoleSubmit()"
      :onCancel="() => handleRoleClose()"
      :okText="roleModalType === 'create' ? $t('createText') : $t('updateText')"
    >
      <role-form :record="record" :types="roleTypeList" :authorities="authorities" ref="roleForm" />
    </Modal>
  </el-card>
</template>

<script>
import RoleForm from './components/RoleForm'
import {
  getRoleList,
  createRole,
  updateRole,
  deleteRole,
  getRoleTypeList,
  enableRole,
  disableRole,
  setRoleDefault,
  getAuthorityTree,
  getRoleById
} from '@/api'
import { Query } from '@/mixins'

import { primaryKey } from './model'

export default {
  mixins: [Query('query')],

  components: { RoleForm },
  data () {
    return {
      dataSource: [],
      loading: false,
      total: 0,
      columns: [
        { prop: 'roleName', label: '角色名' },
        { prop: 'roleTypeValue', label: '角色类型' },
        {
          prop: 'roleStateValue',
          label: '角色状态',
          formatter: row => (
            <el-link
              type={row.roleState !== 1 ? 'danger' : 'success'}
              onClick={() => this.toggleStatus(row.roleState !== 1, row)}
            >
              {row['roleStateValue']}
            </el-link>
          )
        },
        { prop: 'roleSummary', label: '角色描述' },
        {
          prop: 'roleDefault',
          label: '设置默认',
          minWidth: this.$V.cellSize.logic,
          formatter: row => (
            <el-link type="primary" onClick={() => this.setDefaultRole(row)}>
              {row.roleDefault ? '是' : '否'}
            </el-link>
          )
        },

        { prop: 'roleCreateTime', label: '创建时间', width: this.$V.cellSize.date, formatter: row => this.$formatTime(row['roleCreateTime']) },
        { prop: 'roleCreateUserName', label: '创建人' },
        { prop: 'roleUpdateTime', label: '修改时间', width: this.$V.cellSize.date, formatter: row => this.$formatTime(row['roleUpdateTime']) },
        { prop: 'roleUpdateUserName', label: '修改人' },
        {
          label: '操作',
          minWidth: this.$V.cellSize.action,

          formatter: this.getActionDecorator([
            {
              icon: 'el-icon-edit',
              action: this.onClickUpdate,
              auth: this.$P.system.role.update,
              type: 'primary'
            },
            {
              icon: 'el-icon-delete',
              action: this.onClickDelete,
              auth: this.$P.system.role.delete,
              type: 'danger'
            }
          ])
        }
      ],
      row: null,

      // -------- Role Modal ----------
      roleTypeList: [],
      record: {},
      authorities: [],
      roleModalType: '',
      roleModalVisible: false,
      roleModalLoading: false
      // -------- !Role Modal ----------
    }
  },
  methods: {
    // Requests
    // ------------------------------------------
    getAuthorityTree () {
      if (this.authorities.length) {
        return Promise.resolve()
      }

      return this.Catch(getAuthorityTree, {
        onOk ({ data }) {
          this.authorities = data
        }
      })('loading')
    },

    getRoleList (fn) {
      return this.Catch(getRoleList, {
        onOk (res) {
          this.dataSource = res.data.data
          this.total = res.data.total
        }
      })('loading', (fn || this.$noop)(this.query))
    },

    getRoleById (id, { onOk, onError }) {
      return this.Catch(getRoleById, {
        onOk,
        onError
      })('loading', id)
    },

    deleteRole (id, { onOk }) {
      return this.Catch(deleteRole, {
        onOk
      })(null, id)
    },

    createRole (data) {
      return this.Catch(createRole, {
        onOk () {
          this.$message.success(this.$t('createOk'))
          this.getRoleList()
          this.roleModalVisible = false
        }
      })('roleModalLoading', data)
    },

    updateRole (id, data) {
      return this.Catch(updateRole, {
        onOk () {
          this.$message.success(this.$t('updateOk'))
          this.getRoleList()
          this.roleModalVisible = false
        }
      })('roleModalLoading', id, data)
    },

    enableRole (id) {
      return this.Catch(enableRole, {
        onOk () {
          this.$message.success('启用成功')
          this.getRoleList()
        }
      })(null, id)
    },

    disableRole (id) {
      return this.Catch(disableRole, {
        onOk () {
          this.$message.success('禁用成功')
          this.getRoleList()
        }
      })(null, id)
    },

    setRoleDefault (id) {
      return this.Catch(setRoleDefault, {
        onOk () {
          this.$message.success('设置默认角色成功')
          this.getRoleList()
        }
      })(null, id)
    },

    getRoleTypeList () {
      if (this.roleTypeList.length) {
        return Promise.resolve()
      }

      return this.Catch(getRoleTypeList, {
        onOk ({ data }) {
          this.roleTypeList = data.map(it => ({
            label: it.name,
            value: this.$toNumber(it.code)
          }))
        },
        onError () {}
      })('loading')
    },

    // Table
    // ------------------------------------------
    toggleStatus (willEnable, row) {
      const message = willEnable
        ? '确认要启用所选的角色？'
        : '确认要禁用所选的角色？'
      this.MessageBox({
        type: 'warning',
        message,
        onOk: () =>
          willEnable
            ? this.enableRole(row[primaryKey])
            : this.disableRole(row[primaryKey])
      })
    },

    setDefaultRole (row) {
      this.MessageBox({
        type: 'warning',
        message: '确认要设置所选角色为默认？',
        onOk: () => this.setRoleDefault(row[primaryKey])
      })
    },

    ensureAllList () {
      const tasks = Promise.all([
        this.getRoleTypeList(),
        this.getAuthorityTree()
      ])
      return this.Catch(tasks, {
        onError () {}
      })('loading')
    },

    onClickDelete (row) {
      this.ConfirmDelete({
        onOk: () =>
          this.deleteRole(row[primaryKey], {
            onOk () {
              this.$message.success(this.$t('deleteOk'))
              this.getRoleList()
            }
          })
      })
    },

    async onClickUpdate (row) {
      await this.ensureAllList()

      this.getRoleById(row[primaryKey], {
        onOk ({ data }) {
          this.roleModalType = 'update'
          this.record = data
          this.roleModalVisible = true
        }
      })
    },

    async onClickCreate () {
      await this.ensureAllList()

      this.roleModalType = 'create'
      this.record = {}
      this.roleModalVisible = true
    },

    // Modal
    // ------------------------------------------

    // 关闭modal清理数据
    handleClose () {
      this.visible = false
    },

    handleRoleSubmit () {
      this.$refs.roleForm.submit((valid, values) => {
        if (valid) {
          if (this.roleModalType === 'create') {
            this.createRole(values)
          } else {
            this.updateRole(values[primaryKey], values)
          }
        }
      })
    },

    handleRoleClose () {
      this.roleModalVisible = false
      this.record = {}
      this.roleModalType = ''
    }
  },
  computed: {},

  created () {
    this.getRoleList()
    this.inject(this.getRoleList)
  }
}
</script>
